package com.hxxy.wyp.petsLover.common.services.base.fronted.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.time.LocalDate;

import com.hxxy.wyp.petsLover.common.entities.*;
import com.hxxy.wyp.petsLover.common.entities.vo.req.RuleFormReq;
import com.hxxy.wyp.petsLover.common.entities.vo.req.UserLoginInfo;
import com.hxxy.wyp.petsLover.common.entities.vo.req.UserRegisterReq;
import com.hxxy.wyp.petsLover.common.entities.vo.req.ValidatedCodeReq;
import com.hxxy.wyp.petsLover.common.entities.vo.resp.AuthInfo;
import com.hxxy.wyp.petsLover.common.entities.vo.resp.CenterInfoVo;
import com.hxxy.wyp.petsLover.common.mapper.*;
import com.hxxy.wyp.petsLover.common.services.base.fronted.UserService;
import com.hxxy.wyp.petsLover.config.RedisConfig;
import com.hxxy.wyp.petsLover.exception.AppException;
import com.hxxy.wyp.petsLover.security.SecurityContextFrontUser;
import com.hxxy.wyp.petsLover.utils.EncryptUtils;
import com.hxxy.wyp.petsLover.utils.ValidatedUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.LocalDateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @ClassName UserServiceImpl
 * @Description TODO
 * @Author wyp
 * @Date 2023/1/2 20:10
 * @Version 1.0
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    private static final Log logger = LogFactory.getLog(UserServiceImpl.class);

    protected static final java.util.ResourceBundle STRING_RES = java.util.ResourceBundle.getBundle("strings/base/user");
    //静态资源
    private static final String USER_USERNAME_IS_NOT_EMPTY = STRING_RES.getString("user.username.is.not.empty");
    private static final String USER_PASSWORD_IS_NOT_EMPTY = STRING_RES.getString("user.password.is.not.empty");
    private static final String USER_PASSWORD_IS_NOT_LESS_THAN_SIX = STRING_RES.getString("user.password.is.not.less.than.six");
    private static final String USER_PHONE_IS_NOT_EMPTY = STRING_RES.getString("user.phone.is.not.empty");
    private static final String USER_PHONE_IS_MUST_ELEVEN = STRING_RES.getString("user.phone.is.must.eleven");
    private static final String USER_EMAIL_IS_NOT_EMPTY = STRING_RES.getString("user.email.is.not.empty");
    private static final String USER_EMAIL_IS_MUST_CONTAIN_SPECIAL = STRING_RES.getString("user.email.is.must.contain.special");
    private static final String USER_NICKNAME_IS_NOT_EMPTY = STRING_RES.getString("user.nickname.is.not.empty");
    private static final String USER_SEX_IS_NOT_EMPTY = STRING_RES.getString("user.sex.is.not.empty");
    private static final String USER_PIC_IS_NOT_EMPTY = STRING_RES.getString("user.pic.is.not.empty");
    private static final String USER_BIRTHDAY_IS_NOT_EMPTY = STRING_RES.getString("user.birthday.is.not.empty");
    private static final String USER_CONSTELLATION_IS_NOT_EMPTY = STRING_RES.getString("user.constellation.is.not.empty");
    private static final String USER_AREA_IS_NOT_EMPTY = STRING_RES.getString("user.area.is.not.empty");

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserShareMapper userShareMapper;

    @Resource
    private MessageMapper messageMapper;

    @Resource
    private OrdersMapper ordersMapper;

    @Resource
    private ShopCartMapper shopCartMapper;

    @Resource
    private MessageReplyMapper messageReplyMapper;

    @Resource
    private GoodMapper goodMapper;

    @Resource
    private JavaMailSenderImpl mailSender;

    @Autowired
    private RedisConfig redisConfig;

    @Autowired
    private SecurityContextFrontUser securityContextFrontUser;

    @Override
    public Integer updateByUser(User user) {
        ValidatedUtils.validateNotEmpty(user.getUserName(), USER_USERNAME_IS_NOT_EMPTY);
        ValidatedUtils.validateNotEmpty(user.getUserPassword(), USER_PASSWORD_IS_NOT_EMPTY);
        ValidatedUtils.validatePassword(user.getUserPassword(), 6, USER_PASSWORD_IS_NOT_LESS_THAN_SIX);
        ValidatedUtils.validateNotEmpty(user.getPhone(), USER_PHONE_IS_NOT_EMPTY);
        ValidatedUtils.validatePhone(user.getPhone(), 11, USER_PHONE_IS_MUST_ELEVEN);
        ValidatedUtils.validateNotEmpty(user.getEmail(), USER_EMAIL_IS_NOT_EMPTY);
        ValidatedUtils.validateEmail(user.getEmail(), USER_EMAIL_IS_MUST_CONTAIN_SPECIAL);
        ValidatedUtils.validateNotEmpty(user.getNickname(), USER_NICKNAME_IS_NOT_EMPTY);
        ValidatedUtils.validateNotEmpty(user.getSex(), USER_SEX_IS_NOT_EMPTY);
        ValidatedUtils.validateNotEmpty(user.getPic(), USER_PIC_IS_NOT_EMPTY);
        ValidatedUtils.validateNotEmpty(user.getBirthday(), USER_BIRTHDAY_IS_NOT_EMPTY);
        ValidatedUtils.validateNotEmpty(user.getConstellation(), USER_CONSTELLATION_IS_NOT_EMPTY);
        ValidatedUtils.validateNotEmpty(user.getArea(), USER_AREA_IS_NOT_EMPTY);
        return userMapper.updateById(user);

    }

    @Override
    public Page pageSearch(Page pageInfo, LambdaQueryWrapper<User> lambdaQueryWrapper) {
        return userMapper.selectPage(pageInfo, lambdaQueryWrapper);
    }

    @Override
    public Integer enableOrDisableUser(Long id) {
        User user = userMapper.selectById(id);
        if ("0".equals(user.getStatus())) {
            user.setStatus("1");
        } else {
            user.setStatus("0");
        }
        return userMapper.updateById(user);
    }

    @Override
    public Integer updatePass(RuleFormReq ruleFormReq) {
        User user = new User();
        User userInfo = userMapper.selectById(ruleFormReq.getId());
        String curOldPass = EncryptUtils.encryptPassword(ruleFormReq.getUserName(), ruleFormReq.getOldPass());
        if (!curOldPass.equals(userInfo.getUserPassword())) {
            throw new AppException("500", "原密码输入不正确!");
        }
        String curPass = EncryptUtils.encryptPassword(ruleFormReq.getUserName(), ruleFormReq.getPass());
        user.setUserPassword(curPass);
        logger.info("加盐后密码" + curPass);
        user.setId(Long.parseLong(ruleFormReq.getId()));
        return userMapper.updateById(user);
    }

    @Override
    public AuthInfo login(UserLoginInfo userLoginInfo) {
        AuthInfo authInfo = new AuthInfo();
        User user = null;
        if (userLoginInfo.getUserInfo().getUserName() != null && userLoginInfo.getUserInfo().getPassword() != null && StringUtils.isBlank(userLoginInfo.getUserInfo().getEmail())) {
            String password = EncryptUtils.encryptPassword(userLoginInfo.getUserInfo().getUserName(), userLoginInfo.getUserInfo().getPassword());
            LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(User::getUserName, userLoginInfo.getUserInfo().getUserName()).eq(User::getUserPassword, password);
            user = baseMapper.selectOne(lambdaQueryWrapper);
        } else if (StringUtils.isBlank(userLoginInfo.getUserInfo().getUserName()) && userLoginInfo.getUserInfo().getPassword() != null && userLoginInfo.getUserInfo().getEmail() != null) {
            LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(User::getEmail, userLoginInfo.getUserInfo().getEmail());
            User cur = userMapper.selectOne(lambdaQueryWrapper);
            String password = EncryptUtils.encryptPassword(cur.getUserName(), userLoginInfo.getUserInfo().getPassword());
            lambdaQueryWrapper.eq(User::getUserPassword, password);
            user = userMapper.selectOne(lambdaQueryWrapper);
        } else {
            throw new AppException("500", "系统错误!");
        }
        if (user == null) {
            throw new AppException("500", STRING_RES.getString(ExceptionConst.USERNAME_OR_PASSWORD_IS_WRONG));
        }
        if ("1".equals(user.getStatus())) {
            throw new AppException("500", STRING_RES.getString(ExceptionConst.USER_ACCOUNT_IS_BAN));
        }
        StpUtil.login(user.getId());
        user.setIsOnline("1");
        securityContextFrontUser.setUserInfo(user);
//        redisConfig.getRedisTemplateByDb(2).opsForValue().set(user.getId().toString(), "1");
//        redisConfig.getRedisTemplateByDb(2).expire(user.getId().toString(), 300, TimeUnit.SECONDS);
        userMapper.updateById(user);
        authInfo.setUser(user);
        authInfo.setToken(StpUtil.getTokenValue());
        return authInfo;
    }

    @Override
    public void logout() {
        User userInfo = securityContextFrontUser.getUserInfo();
        StpUtil.logout(userInfo.getId());
    }

    @Override
    public void sendSaleBackMsg(String orderId) {
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setFrom("2942646701@qq.com");
        simpleMailMessage.setTo("2942646701@qq.com");
        simpleMailMessage.setSubject("售后处理:");
        simpleMailMessage.setText(orderId + "此笔订单需要进行售后处理！");
        mailSender.send(simpleMailMessage);
    }

    /**
     * 获取验证码
     */
    @Override
    public void getCode(ValidatedCodeReq validatedCodeReq) {
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setFrom("2942646701@qq.com");
        simpleMailMessage.setTo(validatedCodeReq.getEmail());
        simpleMailMessage.setSubject("您的注册验证码为:");
        String code = RandomStringUtils.randomNumeric(6);
        simpleMailMessage.setText(code);
        String key = "code" + ":" + validatedCodeReq.getEmail();
        redisConfig.getRedisTemplateByDb(0).opsForValue().set(key, code);
        redisConfig.getRedisTemplateByDb(0).expire(key, 300, TimeUnit.SECONDS);
        mailSender.send(simpleMailMessage);
    }

    @Override
    public Integer register(UserRegisterReq userRegisterReq) {
        ValidatedUtils.validateNotEmpty(userRegisterReq.getEmail(), USER_EMAIL_IS_NOT_EMPTY);
        ValidatedUtils.validateEmail(userRegisterReq.getEmail(), USER_EMAIL_IS_MUST_CONTAIN_SPECIAL);
        User user = new User();
        String code = userRegisterReq.getCode();
        String codeRedis = (String) redisConfig.getRedisTemplateByDb(0).opsForValue().get("code:" + userRegisterReq.getEmail());
        if (!code.equals(codeRedis)) {
            throw new AppException("500", "验证码不正确!请重新输入");
        }
        ValidatedUtils.validateNotEmpty(userRegisterReq.getUserName(), USER_USERNAME_IS_NOT_EMPTY);
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getUserName, userRegisterReq.getUserName())
                .or().eq(User::getEmail, userRegisterReq.getEmail());
        User selectOne = userMapper.selectOne(lambdaQueryWrapper);
        Optional.ofNullable(selectOne).ifPresent(it -> {
            throw new AppException("500", "用户名或者邮箱已存在!");
        });
        ValidatedUtils.validateNotEmpty(userRegisterReq.getUserPassword(), USER_PASSWORD_IS_NOT_EMPTY);
        ValidatedUtils.validatePassword(userRegisterReq.getUserPassword(), 6, USER_PASSWORD_IS_NOT_LESS_THAN_SIX);
        ValidatedUtils.validateNotEmpty(userRegisterReq.getPhone(), USER_PHONE_IS_NOT_EMPTY);
        ValidatedUtils.validatePhone(userRegisterReq.getPhone(), 11, USER_PHONE_IS_MUST_ELEVEN);
        ValidatedUtils.validateNotEmpty(userRegisterReq.getNickname(), USER_NICKNAME_IS_NOT_EMPTY);
        ValidatedUtils.validateNotEmpty(userRegisterReq.getSex(), USER_SEX_IS_NOT_EMPTY);
        ValidatedUtils.validateNotEmpty(userRegisterReq.getPic(), USER_PIC_IS_NOT_EMPTY);
        ValidatedUtils.validateNotEmpty(userRegisterReq.getBirthday(), USER_BIRTHDAY_IS_NOT_EMPTY);
        ValidatedUtils.validateNotEmpty(userRegisterReq.getConstellation(), USER_CONSTELLATION_IS_NOT_EMPTY);
        ValidatedUtils.validateNotEmpty(userRegisterReq.getArea(), USER_AREA_IS_NOT_EMPTY);
        BeanUtils.copyProperties(userRegisterReq, user);
        String encryptPassword = EncryptUtils.encryptPassword(userRegisterReq.getUserName(), userRegisterReq.getUserPassword());
        user.setRegistrationTime(LocalDate.now());
        user.setUserPassword(encryptPassword);
        return baseMapper.insert(user);
    }

    @Override
    public CenterInfoVo getCenterInfo() {
        CenterInfoVo centerInfoVo = new CenterInfoVo();
        Map<String, Long> map = new HashMap<>();
        User userInfo = securityContextFrontUser.getUserInfo();
        centerInfoVo.setUser(userInfo);
        LambdaQueryWrapper<UserShare> lambdaQueryWrapperUserShare = new LambdaQueryWrapper<>();
        lambdaQueryWrapperUserShare.eq(UserShare::getUserId, userInfo.getId());
        List<UserShare> userShares = userShareMapper.selectList(lambdaQueryWrapperUserShare);
        Long userShareLong = userShareMapper.selectCount(lambdaQueryWrapperUserShare);
        userShares.stream().map(userShare -> {
            String sharePic = userShare.getSharePic();
            String[] split = sharePic.split(",");
            sharePic = split[0];
            userShare.setSharePic(sharePic);
            List<String> userSharePicList = Arrays.stream(split).collect(Collectors.toList());
            userShare.setSharePicList(userSharePicList);
            return userShare;
        }).collect(Collectors.toList());
        centerInfoVo.setUserShares(userShares);
        map.put("userShare", userShareLong);
        //我的留言
        LambdaQueryWrapper<Message> lambdaQueryWrapperMessage = new LambdaQueryWrapper<>();
        lambdaQueryWrapperMessage.eq(Message::getUserId, userInfo.getId());
        List<Message> messages = messageMapper.selectList(lambdaQueryWrapperMessage);
        messages.stream().map(message -> {
            LambdaQueryWrapper<MessageReply> lambdaQueryWrapperMessageReply = new LambdaQueryWrapper<>();
            lambdaQueryWrapperMessageReply.eq(MessageReply::getMessageId, message.getId());
            MessageReply messageReply = messageReplyMapper.selectOne(lambdaQueryWrapperMessageReply);
            message.setMessageReply(messageReply);
            return message;
        }).collect(Collectors.toList());
        centerInfoVo.setUserMessage(messages);
        Long messageLong = messageMapper.selectCount(lambdaQueryWrapperMessage);
        map.put("message", messageLong);
        //我的订单
        LambdaQueryWrapper<Orders> lambdaQueryWrapperOrders = new LambdaQueryWrapper<>();
        lambdaQueryWrapperOrders.eq(Orders::getUserId, userInfo.getId());
        List<Orders> orders = ordersMapper.selectList(lambdaQueryWrapperOrders);
        List<Orders> ordersList = orders.stream().map(order -> {
            List<ShopCart> shopCarts = new ArrayList<>();
            List<String> collect = Arrays.stream(order.getShopCartId().split(",")).collect(Collectors.toList());
            collect.forEach(s -> {
                LambdaQueryWrapper<Good> goodLambdaQueryWrapper = new LambdaQueryWrapper<>();
                ShopCart shopCart = shopCartMapper.selectById(s);
                Good good = goodMapper.selectOne(goodLambdaQueryWrapper.eq(Good::getId, shopCart.getGoodId()));
                List<String> picList = Arrays.stream(good.getPic().split(",")).collect(Collectors.toList());
                good.setPic(picList.get(0));
                good.setPicList(picList);
                shopCart.setGood(good);
                shopCarts.add(shopCart);
            });
            order.setShopCarts(shopCarts);
            return order;
        }).collect(Collectors.toList());
        centerInfoVo.setOrdersList(ordersList);
        Long ordersLong = ordersMapper.selectCount(lambdaQueryWrapperOrders);
        map.put("orders", ordersLong);

        centerInfoVo.setSumsByGroup(map);

        return centerInfoVo;

    }
}
